package com.miracle.common.utils;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.htmlparser.Parser;
import org.htmlparser.beans.StringBean;
import org.htmlparser.util.ParserException;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;

import com.google.common.escape.Escaper;
import com.google.common.net.UrlEscapers;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;

import sun.misc.BASE64Encoder;


public class CommonUtils {

    /**
     * 获取时间戳
     * 
     * @return
     */
    public static String getLongTime() {
        long longTime = new Date().getTime();
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return longTime + "";
    }

    /**
     * 判断字符串是否为空
     * 
     * @param str
     * @return
     */
    public static boolean isNullOrEmpty(String str) {
        return str == null || str.trim().length() == 0;
    }

    /**
     * 分页
     * 
     * @param map
     * @return
     */
    public static Map<String, Object> getPage(Map<String, Object> map) {
        Map<String, Object> pageMap = new HashMap<String,Object>(3);
        pageMap.put("pn", map.get("pn"));
        pageMap.put("ps", map.get("ps"));
        pageMap.put("total", map.get("total"));
        return pageMap;
    }

    /**
     * String转MD5
     * 
     * @param plainText
     * @return
     */
    public static String covertpw(String plainText) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(plainText.getBytes());
            byte b[] = md.digest();
            int i;
            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }
            return buf.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return plainText;
    }

    /**
     * 获取配置文件信息
     * 
     * @param key
     * @return
     */
    public static String getPropertiesBykey(String key) {
        String val = "";
        try {
            Resource resource = new ClassPathResource("/message.properties");
            Properties props;
            props = PropertiesLoaderUtils.loadProperties(resource);
            val = (String) props.get(key);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return val;
    }

    /**
     * 获取环境地址配置文件信息
     * 
     * @param key
     * @return
     */
    public static String getSysConfigBykey(String key) {
        String val = "";
        try {
            Resource resource = new ClassPathResource("/sys.properties");
            Properties props;
            props = PropertiesLoaderUtils.loadProperties(resource);
            val = (String) props.get(key);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return val;
    }
    
    /**
     * 获取接口配置信息
     * 
     * @param key
     * @return
     */
    public static String getInterfaceConfigBykey(String key) {
        String val = "";
        try {
            Resource resource = new ClassPathResource("/interface-config.properties");
            Properties props;
            props = PropertiesLoaderUtils.loadProperties(resource);
            val = (String) props.get(key);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return val;
    }
    
    
    /**
     * 获取信息发送模板
     * 
     * @param key
     * @return
     */
    public static String getMsgTemplateBykey(String key) {
        String val = "";
        try {
            Resource resource = new ClassPathResource("/template-config.properties");
            // ① 指定文件资源对应的编码格式（UTF-8）
            EncodedResource encRes = new EncodedResource(resource,"UTF-8"); 
            Properties props =  new  Properties();        
            props.load(encRes.getReader());   
            val = (String) props.get(key);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return val;
    }
    
    /**
     * 获取信息发送模板
     * 
     * @param key
     * @return
     */
    public static String getEnglishMsg(String key) {
        String val = "";
        try {
            Resource resource = new ClassPathResource("/message_en.properties");
            // ① 指定文件资源对应的编码格式（UTF-8）
            EncodedResource encRes = new EncodedResource(resource,"UTF-8"); 
            Properties props =  new  Properties();        
            props.load(encRes.getReader());   
            val = (String) props.get(key);
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        if("".equals(val)){
        	return key;
        }
        return val;
    }
    

    /**
     * url-encode the param
     * 
     * @param param
     * @return
     */
    public static String escape(String param) {
        return escapers.escape(param);
    }

    private static final Escaper escapers = UrlEscapers.urlFormParameterEscaper();
    

	// yms追加 start
	/**
	 * 生成二维码图片 不存储 直接以流的形式输出到页面
	 * @param content
	 * @param response
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static String encodeQrcodeStream(String content){
		if(StringUtils.isBlank(content)) {
			return "";
		}

		MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
		Map hints = new LinkedHashMap();
		hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); //设置字符集编码类型
		BitMatrix bitMatrix = null;
		try {
			bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, 300, 300,hints);
			BufferedImage image = toBufferedImage(bitMatrix);
			//输出二维码图片流
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			ImageIO.write(image, "png", out);
			BASE64Encoder encoder = new BASE64Encoder();
			String imageString = encoder.encode(out.toByteArray());
			return URLEncoder.encode(imageString, "utf-8");

		} catch (Exception e1) {
			e1.printStackTrace();
			return "";
		}
	}
	// yms追加 end

    /**
     * 生成二维码图片 不存储 直接以流的形式输出到页面
     * @param content
     * @param response
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static void encodeQrcode(String content,HttpServletResponse response){
        if(StringUtils.isBlank(content))
            return;
        MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
        Map hints = new HashMap();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); //设置字符集编码类型
        BitMatrix bitMatrix = null;
        try {
            bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, 300, 300,hints);
            BufferedImage image = toBufferedImage(bitMatrix);
            //输出二维码图片流
            try {
                ImageIO.write(image, "png", response.getOutputStream());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } catch (WriterException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }         
    }
    
    private static final int WHITE = 0xFFFFFFFF;
    private static final int BLACK = 0xFF000000;
    private static BufferedImage toBufferedImage(BitMatrix matrix) {
        int width = matrix.getWidth();
        int height = matrix.getHeight();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
          for (int y = 0; y < height; y++) {
            image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
          }
        }
        return image;
   }  
    
    /**
     * 获取2个时间之间的所有日期
     * @param start
     * @param end
     * @param calendarType
     * @return
     */
    public static List<Date> getDateArrays(Date start,Date end ,int calendarType){  
        ArrayList<Date> ret = new ArrayList<Date>();  
        Calendar calendar = Calendar.getInstance();  
        calendar.setTime(start);  
        Date tmpDate = calendar.getTime();  
        long endTime = end.getTime();  
        while(tmpDate.before(end)||tmpDate.getTime() == endTime){  
            ret.add(calendar.getTime());  
            calendar.add(calendarType, 1);  
            tmpDate = calendar.getTime();  
        }         
          
        return ret;        
    }  
    
    
    /**
     * 获取指定日期月份的第一天的下几个月的第几天
     * @param date
     * @param month
     * @param day
     * @return
     */
    public static Date getBillEndDate(Date billStartDate,int month,Date hstart_date){

    	Calendar chstart = Calendar.getInstance();
    	chstart.setTime(hstart_date);
    	int hStartAtDay = chstart.get(Calendar.DAY_OF_MONTH);
    	
    	Calendar cstart = Calendar.getInstance();
    	cstart.setTime(billStartDate);
    	int startDayTmp = cstart.get(Calendar.DAY_OF_MONTH);
    	
    	
    	Date billEndDateTmp = DateUtils.addMonths(billStartDate, month);
    	Calendar cend = Calendar.getInstance();
    	cend.setTime(billEndDateTmp);
    	int endDayTmp = cend.get(Calendar.DAY_OF_MONTH);
    	
    	
    	if(startDayTmp == endDayTmp && hStartAtDay == endDayTmp){
    		return DateUtils.addDays(DateUtils.addMonths(billStartDate, month),-1);
    	}
    	
    	
    	if(hStartAtDay >= startDayTmp){
    		if(startDayTmp == 1){
    			if(month > 1){
    				cstart.add(Calendar.MONTH, month-1);
    			}
    			cstart.set(Calendar.DAY_OF_MONTH, hStartAtDay-1);
    			return cstart.getTime();
    		}else{
    			cend.set(Calendar.DAY_OF_MONTH, endDayTmp);
    			return cend.getTime();
    		}
    		
    	}

		String billStartMonthEndDayStr = getMonthEnd(date2strYMD(billStartDate),0);
    	Date billStartMonthEndDay = str2dateYMD(billStartMonthEndDayStr);
    	
    	String billEndMonthEndDayStr = getMonthEnd(date2strYMD(billStartDate),month);
    	Date billEndMonthEndDay = str2dateYMD(billEndMonthEndDayStr);
    	
    	int daysRange = (int)daysBetween(billStartDate, billStartMonthEndDay);
    	
    	return DateUtils.addDays(billEndMonthEndDay,-daysRange+1);
    	
    }
    
    
    /**
     * 获取指定日期月份的第一天的下几个月的第几天
     * @param date
     * @param month
     * @param day
     * @return
     */
    public static String getMonthFirst(String date,int month,int day){
    	try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Calendar cal = Calendar.getInstance();
			cal.setTime(sdf.parse(date));
			String str = "";
			cal.add(Calendar.MONTH,month);
			cal.set(Calendar.DATE, day);
			str=sdf.format(cal.getTime());
			return str;
		} catch (ParseException e) {
			e.printStackTrace();
		}
    	return null;
    }
    
    /**
     * 获取指定日期月份的第一天的下几个月的最后一天
     * @param date
     * @param month
     * @param day
     * @return
     */
    public static String getMonthEnd(String date,int month){
    	try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Calendar lastDate = Calendar.getInstance();
			lastDate.setTime(sdf.parse(date));
			lastDate.add(Calendar.MONTH,month);//加一个月
			lastDate.set(Calendar.DATE, 1);//把日期设置为当月第一天
			lastDate.roll(Calendar.DATE, -1);//日期回滚一天，也就是本月最后一天
			String str=sdf.format(lastDate.getTime());
			return str;
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	return null;
    }
    
    /**
     * 计算2个日期相隔多少天
     * @param beginDate
     * @param endDate
     * @return
     */
    public static long daysBetween(String beginDate,String endDate){
    	try {
			SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); 
			Date smdate_=sdf.parse(beginDate); 
			Date bdate_=sdf.parse(endDate); 
			Calendar cal = Calendar.getInstance(); 
			cal.setTime(smdate_); 
			long time1 = cal.getTimeInMillis(); 
			cal.setTime(bdate_); 
			long time2 = cal.getTimeInMillis(); 
			long between_days=(time2-time1)/(1000*3600*24);
			return between_days+1;
		} catch (ParseException e) {
			e.printStackTrace();
		}
    	return 0;
    }
    
    
    
    
    /**
     * 计算2个日期相隔多少小时分钟
     * @param beginDate
     * @param endDate
     * @return
     */
    public static String hoursminuteBetween(Date beginDate,Date endDate){
    	
			Date smdate_=beginDate; 
			Date bdate_=endDate; 
			Calendar cal = Calendar.getInstance(); 
			cal.setTime(smdate_); 
			long time1 = cal.getTimeInMillis(); 
			cal.setTime(bdate_); 
			long time2 = cal.getTimeInMillis(); 
			long between_minutes=(time2-time1)/(1000*60);
			long hour=between_minutes/60;
			long minute=between_minutes-hour*60;
			if(hour==0){
				return between_minutes+"分";
			}
			if(minute==0){
				return hour+"小时";
			}
			return hour+"小时"+minute+"分";
    }
    
    
    
    
    
    /**
     * 计算2个日期相隔多少天
     * @param beginDate
     * @param endDate
     * @return
     */
    public static long daysBetween(Date beginDate,Date endDate){
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); 
		String begindate = sdf.format(beginDate);
		String enddate = sdf.format(endDate);
		
		return daysBetween(begindate,enddate);
    }
    
    
    /**
     * 计算2个日期相隔多少月(一个月零5天计算为：1+5/当月总天数 )
     * @param beginDate
     * @param endDate
     * @param allHireStartDate 订单总租约开始时间
     * @return
     */
    public static BigDecimal monthsBetween(Date beginDate,Date endDate,Date allHireStartDate){
		long fullMonCnt = 0L;
		
		Date tempDate = beginDate;
    	while(true){
    		 tempDate = getBillEndDate(tempDate, 1,allHireStartDate);
    		 if(tempDate.before(endDate)){
    			 tempDate=DateUtils.addDays(tempDate,1);
    			 fullMonCnt++ ;
    		 }else{
    			 break;
    		 }
    	}
    	
    	//计算最后一个完整月后还多出多少天
    	Date overStartDate = DateUtils.addDays(getBillEndDate(beginDate, (int)fullMonCnt,allHireStartDate) ,1);
    	if(fullMonCnt == 0){
    		overStartDate = beginDate;
    	}
    	
    	BigDecimal lastMonthDays =new BigDecimal(daysBetween(overStartDate,endDate));
    	BigDecimal lastMonthAllDays =new BigDecimal(daysBetween(overStartDate,tempDate));
    	
    	return lastMonthDays.divide(lastMonthAllDays,18,RoundingMode.HALF_UP).add(new BigDecimal(fullMonCnt)).setScale(18, RoundingMode.HALF_UP);
    }
    
    /**
     * 计算2个日期相隔多少月(一个月零5天计算为：1+5/当月总天数 )
     * @param beginDate
     * @param endDate
     * @param allHireStartDate 订单总租约开始时间
     * @return
     */
    public static BigDecimal monthsBetweenFixed(Date beginDate,Date endDate,String billStartdate){
    	// 固定出账日获取
    	int static_out_start = Integer.parseInt(billStartdate);
    	
    	Calendar csdate = Calendar.getInstance();
    	csdate.setTime(beginDate);

    	int startDay = csdate.get(Calendar.DAY_OF_MONTH);
    	
    	// 账期开始日正好是固定出账日时，直接在账期开始日出账
    	if(static_out_start == startDay){
    		return monthsBetween(beginDate,endDate,beginDate);
    	}
    	
    	csdate.set(Calendar.DAY_OF_MONTH, static_out_start);
    	
    	// 固定出账日在账期开始日之后时，前推一个月出账，并且要和系统时间比较取靠后者
    	if(static_out_start > startDay){
    		long allmonthdays = daysBetween(DateUtils.addMonths(csdate.getTime(), -1),DateUtils.addDays(csdate.getTime(),-1));
    		
    		long hiredays = daysBetween(DateUtils.addMonths(csdate.getTime(), -1),beginDate);
    		
    		return new BigDecimal(hiredays).divide(new BigDecimal(allmonthdays),18,RoundingMode.HALF_UP);
    	}
    	
    	// 固定出账日在当前账期开始日之前时，取账期开始日所在月的出账日
    	if(static_out_start < startDay){
    		long allmonthdays = daysBetween(csdate.getTime(),DateUtils.addDays(DateUtils.addMonths(csdate.getTime(), 1),-1));
    		
    		long hiredays = daysBetween(beginDate,DateUtils.addDays(DateUtils.addMonths(csdate.getTime(), 1),-1));
    		
    		return new BigDecimal(hiredays).divide(new BigDecimal(allmonthdays),18,RoundingMode.HALF_UP);
    	}
    	
    	return null;
    }
    
    /**
     * 计算2个日期相隔多少月多少天
     * @param beginDate
     * @param endDate
     * @return
     */
    public static String monthsAndDaysBetween(Date beginDate,Date endDate){
		long fullMonCnt = 0L;
		
		Date tempDate = beginDate;
    	while(true){
    		 tempDate = DateUtils.addMonths(tempDate, 1);
    		 if(tempDate.before(endDate)){
    			 fullMonCnt++ ;
    		 }else{
    			 break;
    		 }
    	}
    	
    	BigDecimal lastMonthDays =new BigDecimal(daysBetween(DateUtils.addMonths(beginDate, (int)fullMonCnt),endDate));
    	
    	if(fullMonCnt == 0L){
    		return lastMonthDays+"天";
    	}
    	
    	return fullMonCnt+"个月"+lastMonthDays+"天";
    }
    
    /**
     * 解析获取HTML中的文本内容
     * 
     * @param inputHtml
     * @return
     * @throws ParserException
     */
    public static String getTextFromHtml(String inputHtml) throws ParserException{
    	if(StringUtils.isEmpty(inputHtml)){
    		return "";
    	}
    	
    	Parser pa = new Parser();
		pa.setInputHTML(inputHtml);
		
		
		//TextExtractingVisitor visitor = new TextExtractingVisitor();
		//pa.visitAllNodesWith(visitor);
		//return visitor.getExtractedText();
		
		StringBean sb = new StringBean();
		sb.setLinks(false);
		sb.setReplaceNonBreakingSpaces(true);
		pa.visitAllNodesWith(sb);
		if(sb.getStrings() == null){
			return null;
		}
    	return sb.getStrings().replace("\n", "");
    }
    
    /**
     * 金额数字转大写
     * 
     * @param point
     * @return
     * @throws ParserException
     */
    public static String getPointUpp(String s) throws ParserException{

        s = s.replaceAll("\\.", "");  
        char[] digit = { '零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖' };  
        String unit = "仟佰拾兆仟佰拾亿仟佰拾万仟佰拾元角分";  
        int l = unit.length();  
        StringBuffer sb = new StringBuffer(unit);  
        for (int i = s.length() - 1; i >= 0; i--)  
            sb = sb.insert(l - s.length() + i, digit[(s.charAt(i) - 0x30)]);  
        s = sb.substring(l - s.length(), l + s.length());  
        s = s.replaceAll("零[拾佰仟]", "零").replaceAll("零{2,}", "零").replaceAll("零([兆万元])", "$1").replaceAll("零[角分]", "");  
        if (s.endsWith("角"))  
            s += "零分";  
        if (!s.contains("角") && !s.contains("分") && s.contains("元"))  
            s += "整";  
        if (s.contains("分") && !s.contains("整") && !s.contains("角"))  
            s = s.replace("元", "元零");  
        return s;
    }
    
  
    /**
     * 字符串格式转换为date格式
     * @param datetime
     * @return
     */
    public static Date str2dateYMD(String datetime){
    	try {
    		String dateType=CommonUtils.getSysConfigBykey("dateType");
    		SimpleDateFormat sdf = new SimpleDateFormat(dateType);
			Date date = sdf.parse(datetime);
			return date;
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	return null;
    }
    
    
    /**
     * 字符串格式转换为date格式
     * @param datetime
     * @return
     */
    public static Date str2dateYM(String datetime){
    	try {
    		String dateType="yyyy-MM";
    		SimpleDateFormat sdf = new SimpleDateFormat(dateType);
			Date date = sdf.parse(datetime);
			return date;
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	return null;
    }
    
    
    
    /**
     * 字符串格式转换为date格式
     * @param datetime
     * @return
     */
    public static Date str2dateYMDHMS(String datetime){
    	try {
    		String dateType=CommonUtils.getSysConfigBykey("dateTypeYMDHMS");
    		SimpleDateFormat sdf = new SimpleDateFormat(dateType);
			Date date = sdf.parse(datetime);
			return date;
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	return null;
    }
    /**
     * date格式转换为字符串格式
     * @param datetime
     * @return
     */
    public static String date2strYMD(Date datetime){
    	try {
    		String dateType=CommonUtils.getSysConfigBykey("dateType");
    		SimpleDateFormat sdf = new SimpleDateFormat(dateType);
    		String time=sdf.format(datetime);
			return time;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	return null;
    }
    
    /**
     * date格式转换为字符串格式Y
     * @param datetime
     * @return
     */
    public static String date2strY(Date datetime){
    	try {
    		String dateType="yyyy";
    		SimpleDateFormat sdf = new SimpleDateFormat(dateType);
    		String time=sdf.format(datetime);
			return time;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	return null;
    }
    
    
    
    /**
     * 字符串格式转换为date格式
     * @param datetime
     * @return
     */
    public static Date str2dateYMDHM(String datetime){
    	try {
    		String dateType=CommonUtils.getSysConfigBykey("dateTypeYMDHM");
    		SimpleDateFormat sdf = new SimpleDateFormat(dateType);
			Date date = sdf.parse(datetime);
			return date;
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	return null;
    }
    /**
     * date格式转换为字符串格式
     * @param datetime
     * @return
     */
    public static String date2strYMDHM(Date datetime){
    	try {
    		String dateType=CommonUtils.getSysConfigBykey("dateTypeYMDHM");
    		SimpleDateFormat sdf = new SimpleDateFormat(dateType);
    		String time=sdf.format(datetime);
			return time;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	return null;
    }
    
    
    
    
    
    
    
    /**
     * date格式转换为字符串格式（年月）
     * @param datetime
     * @return
     */
    public static String date2strYM(Date datetime){
    	try {
    		
    		String dateType="yyyy-MM";
    		SimpleDateFormat sdf = new SimpleDateFormat(dateType);
    		String time=sdf.format(datetime);
			return time;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	return null;
    }
    
    
    
    
    
    /**
     * date格式转换为字符串格式(时分)
     * @param datetime
     * @return
     */
    public static String date2strHM(Date datetime){
    	try {
    		String dateType=CommonUtils.getSysConfigBykey("dateTypeHM");
    		SimpleDateFormat sdf = new SimpleDateFormat(dateType);
    		String time=sdf.format(datetime);
			return time;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	return null;
    }
    
    /**
     * String格式转换为date格式(时分)
     * @param datetime
     * @return
     */
    public static Date str2dateHM(String datetime){
    	try {
    		String dateType=CommonUtils.getSysConfigBykey("dateTypeHM");
    		SimpleDateFormat sdf = new SimpleDateFormat(dateType);
    		Date time=sdf.parse(datetime);
			return time;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	return null;
    }
    
    
    
    
    /**
     * date格式转换为字符串格式
     * @param datetime
     * @return
     */
    public static String date2strYMDHMS(Date datetime){
    	try {
    		String dateType=CommonUtils.getSysConfigBykey("dateTypeYMDHMS");
    		SimpleDateFormat sdf = new SimpleDateFormat(dateType);
    		String time=sdf.format(datetime);
			return time;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	return null;
    }
    
    /**
     * 获取当前日期的开始时间点
     * @param datetime
     * @return
     */
    public static Date getCurrentDateBegin(Date datetime){
    	try {
    		String dateType=CommonUtils.getSysConfigBykey("dateType");
    		SimpleDateFormat sdf = new SimpleDateFormat(dateType);
    		String time=sdf.format(datetime);
    		time=time+" 00:00:00";
    		String dateType2=CommonUtils.getSysConfigBykey("dateTypeYMDHMS");
    		SimpleDateFormat sdf2 = new SimpleDateFormat(dateType2);
    		Date timeres=sdf2.parse(time);
			return timeres;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	return null;
    }
    
    /**
     * 获取当前日期的结束时间点
     * @param datetime
     * @return
     */
    public static Date getCurrentDateEnd(Date datetime){
    	try {
    		String dateType=CommonUtils.getSysConfigBykey("dateType");
    		SimpleDateFormat sdf = new SimpleDateFormat(dateType);
    		String time=sdf.format(datetime);
    		time=time+" 23:59:59";
    		String dateType2=CommonUtils.getSysConfigBykey("dateTypeYMDHMS");
    		SimpleDateFormat sdf2 = new SimpleDateFormat(dateType2);
    		Date timeres=sdf2.parse(time);
			return timeres;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	return null;
    }
    
    /**
     * 获取星期几
     * @param datetime
     * @return
     */
    public static String getWeekDay(Date datetime){
    	SimpleDateFormat sdf = new SimpleDateFormat("EEEE",Locale.CHINA);
		String week = sdf.format(datetime);
		return week;

    }
    
    /**
     * APP 计算等待支付还剩多少秒
     * @param launchTime
     * @param now
     * @return
     */
    public static long calculateRemindSeconds(Date launchTime,Date now){
    	String payContinueMinute=CommonUtils.getSysConfigBykey("pay_continue_time");
		long Minute=Integer.parseInt(payContinueMinute);
		long launch_time=launchTime.getTime();
		long now_time=now.getTime();
		long betweenSeconds=(now_time-launch_time)/1000;
		long remindSeconds=Minute*60-betweenSeconds;
		return remindSeconds;
    }
    
    
    
    /**
     * 转换  例2016-01 to 2016-01-01 00:00:00
     * @param begin_date
     * @throws ParseException 
     */
    public static Date strYM2dateYMDHMSBegin(String begin_date) throws ParseException{
    	String dateType=CommonUtils.getSysConfigBykey("dateTypeYM");
		SimpleDateFormat sdf = new SimpleDateFormat(dateType);
		Date date = sdf.parse(begin_date);  	
		Calendar calendar = Calendar.getInstance();
        calendar.setTime(date); // 设置为当前时间
		//获取月头时间
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }
    
    /**
     * 转换  例2016-01 to 2016-01-31 23:59:59
     * @param end_date
     * @throws ParseException 
     */
    public static Date strYM2dateYMDHMSEnd(String end_date) throws ParseException{
    	String dateType=CommonUtils.getSysConfigBykey("dateTypeYM");
		SimpleDateFormat sdf = new SimpleDateFormat(dateType);
		Date date = sdf.parse(end_date);  	
		Calendar calendar = Calendar.getInstance();
        calendar.setTime(date); // 设置为当前时间
    	//获取月末时间
        calendar.add(Calendar.MONTH, 1);
        calendar.set(Calendar.DAY_OF_MONTH, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }
    
    /**
     * 获取去年这个时候的时间
     * @param time
     * @return
     */
    public static Date getLastYearTime(Date time){
    	Calendar calendar = Calendar.getInstance();
        calendar.setTime(time); // 设置为当前时间
        calendar.add(Calendar.YEAR, -1);//当前时间减去一年，即一年前的时间    
        return calendar.getTime();
    }
    

    /**
     * 获取随机设备领取码
     * @return
     */
    public static String getUnionRandomStr(){
    	String return_str="";
    	
    	String base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";   
        Random random = new Random();   
        StringBuffer sb = new StringBuffer();   
        for (int i = 0; i < 6; i++) {   
            int number = random.nextInt(base.length());   
            sb.append(base.charAt(number));   
        }   
        //前半部分字符串
        String head_str=sb.toString();
        //后半部分字符串
        sb = new StringBuffer();  
        for (int i = 0; i < 8; i++) {   
            int number = random.nextInt(base.length());   
            sb.append(base.charAt(number));   
        }
        String foot_str=sb.toString();
        
        return_str=head_str+"_"+foot_str;
        
        return return_str;   
    }
    
    
    

    /**
     * 计算2个日期相隔多少分钟
     * @param beginDate
     * @param endDate
     * @return
     */
    public static long minuteBetween(Date beginDate,Date endDate){
    	
			Date smdate_=beginDate; 
			Date bdate_=endDate; 
			Calendar cal = Calendar.getInstance(); 
			cal.setTime(smdate_); 
			long time1 = cal.getTimeInMillis(); 
			cal.setTime(bdate_); 
			long time2 = cal.getTimeInMillis(); 
			long between_minutes=(time2-time1)/(1000*60);
			
			return between_minutes;
    }
    
    /**
     * 获取出账日
     * @param bill_start_date
     * @param billStartDate
     * @return
     * @throws ParseException 
     */
    public static Date getBillOutDate(String bill_out_date,Date billStartDate,BigDecimal payCycle){
    	
    	/*
    	//获取billStartDate 所在月的出账日
    	Calendar calendar = Calendar.getInstance();
        calendar.setTime(billStartDate); // 设置为当前时间
    	//设定当前月的出账日
        Integer day=Integer.parseInt(bill_out_date);
        Date resDate=calendar.getTime();
        resDate=DateUtils.addMonths(billStartDate, payCycle.intValue()-1);//多个月周期
        if(day == 1){
        	resDate=DateUtils.addMonths(resDate, 1);
        	resDate=DateUtils.setDays(resDate,1);
        	resDate=DateUtils.addDays(resDate, -1);
        	resDate=getCurrentDateEnd(resDate);
        }else{      	
        	resDate=DateUtils.setDays(resDate,day);
        	resDate=getCurrentDateEnd(resDate);
        	if(resDate.after(billStartDate)){
        		resDate=DateUtils.addMonths(resDate, -1);
        	}
        }
    	return resDate;
    	*/
    	
    	// 固定出账日获取
    	int static_out_start = Integer.parseInt(bill_out_date);
    	
    	Calendar csdate = Calendar.getInstance();
    	csdate.setTime(billStartDate);

    	int startDay = csdate.get(Calendar.DAY_OF_MONTH);
    	
    	// 账期开始日正好是固定出账日时，直接在账期开始日出账
    	if(static_out_start == startDay){
    		return billStartDate;
    	}
    	
    	// 固定出账日在账期开始日之后时，前推一个月出账，并且要和系统时间比较取靠后者
    	if(static_out_start > startDay){
    		csdate.set(Calendar.DAY_OF_MONTH, static_out_start);
    		Date billOutDate = DateUtils.addMonths(csdate.getTime(),-1);
    		return billOutDate.before(new Date())? new Date():billOutDate;
    	}
    	
    	// 固定出账日在当前账期开始日之前时，取账期开始日所在月的出账日
    	if(static_out_start < startDay){
    		csdate.set(Calendar.DAY_OF_MONTH, static_out_start);
    		return csdate.getTime();
    	}
    	
    	return null;
    }
    
    /**
     * 获取最终付款日 yyyy-mm-dd 23:59:59
     * @param bill_start_date
     * @param billStartDate
     * @return
     * @throws ParseException 
     */
    public static Date getBillLatPayDate(String bill_last_pay_date,Date billStartDate){
    	/*
    	//获取billStartDate 所在月的最终付款日
    	Calendar calendar = Calendar.getInstance();
        calendar.setTime(billStartDate); // 设置为当前时间
    	//设定当前月的最终付款日
        Integer day=Integer.parseInt(bill_last_pay_date);
        Date resDate=calendar.getTime();
        resDate=DateUtils.addMonths(billStartDate, payCycle.intValue()-1);//多个月周期
        if(day == 1){
        	resDate=DateUtils.addMonths(resDate, 1);
        	resDate=DateUtils.setDays(resDate,1);
        	resDate=DateUtils.addDays(resDate, -1);
        	resDate=getCurrentDateEnd(resDate);
        }else{
        	resDate=DateUtils.setDays(resDate,day);
        	resDate=getCurrentDateEnd(resDate);
        	if(resDate.before(billStartDate)){
        		resDate=DateUtils.addMonths(resDate, 1);
        	}
        }
//        day=day-1;
//        calendar.set(Calendar.DAY_OF_MONTH, day);
//        calendar.set(Calendar.HOUR_OF_DAY, 23);
//        calendar.set(Calendar.MINUTE, 59);
//        calendar.set(Calendar.SECOND, 59);
//        Date resDate=calendar.getTime();
//    	if(resDate.before(billStartDate)){
//    		resDate=DateUtils.addMonths(resDate, 1);
//    	}
    	return resDate;
    	*/
    	
    	// 最终付款日获取
    	// 固定记账开始日
    	int daysBetweenStartdate = Integer.parseInt(bill_last_pay_date);
    	return DateUtils.addDays(billStartDate,daysBetweenStartdate);
    }
    
    
    /**
     * 获取本期账单完租时间
     * @param bill_start_date
     * @param billStartDate
     * @return
     * @throws ParseException 
     */
    public static Date getBillEndDateFixDay(String bill_start_date,Date billStartDate,BigDecimal payCycle){
    	/*
    	//Calendar calendar = Calendar.getInstance();      
    	//设定当前月的出账日
        Integer day=Integer.parseInt(bill_start_date);
        Date resDate=new Date();
    	Calendar calendar = Calendar.getInstance();
        calendar.setTime(billStartDate); // 设置为当前时间
        //获取当前是这个月的第一天
        int a=calendar.get(Calendar.DAY_OF_MONTH);  
        if(tag!=1){
        	resDate=DateUtils.addMonths(billStartDate, payCycle.intValue()-1);//多个月周期
        }else{
        	if(a==day){
        		resDate=DateUtils.addMonths(billStartDate, payCycle.intValue()-1);//多个月周期
        	}
        }
        
        if(day == 1){        	
        	resDate=DateUtils.addMonths(resDate, 1);
        	resDate=DateUtils.setDays(resDate,1);
        	resDate=DateUtils.addDays(resDate, -1);
        	resDate=getCurrentDateEnd(resDate);
        }else{
        	resDate=DateUtils.setDays(resDate,day-1);
        	resDate=getCurrentDateEnd(resDate);
        	if(resDate.before(billStartDate)){
        		resDate=DateUtils.addMonths(resDate, 1);
        	}
        }
        */
    	
    	// 固定记账开始日
    	int static_bill_start = Integer.parseInt(bill_start_date);
    	
    	Calendar csdate = Calendar.getInstance();
    	csdate.setTime(billStartDate);

    	int startDay = csdate.get(Calendar.DAY_OF_MONTH);
    	
    	// 账期开始日正好是固定记账开始日时，直接按照支付周期计算账期截止日
    	if(static_bill_start == startDay){
    		return DateUtils.addDays(DateUtils.addMonths(billStartDate, payCycle.intValue()),-1);
    	}
    	
    	// 固定记账开始日在当前账期开始日之后时，本期账期结束日为当前账期开始日
    	if(static_bill_start > startDay){
    		csdate.set(Calendar.DAY_OF_MONTH, static_bill_start);
    		return DateUtils.addDays(csdate.getTime(),-1);
    		//return DateUtils.addDays(date, amount)
    	}
    	
    	// 固定记账开始日在当前账期开始日之前时，本期账期结束日为下月固定记账开始日的前一天
    	if(static_bill_start < startDay){
    		csdate.set(Calendar.DAY_OF_MONTH, static_bill_start);
    		return DateUtils.addDays(DateUtils.addMonths(csdate.getTime(), 1),-1);
    	}
    	
    	return null;
    }
    
    
    /**
     * 千分位转换
     * @param price
     * @return
     */
    public static String thousandsFormat(BigDecimal price){
    	if(price == null){
    		return "0";
    	}
	    BigDecimal b = price;//,代表分隔符  
	    DecimalFormat d1 =new DecimalFormat("#,##0.00;(#)");//0.后面的##代表位数 如果换成0 效果就是位数不足0补齐
	    if(b.compareTo(new BigDecimal("0")) < 0){
	    	BigDecimal c=b.multiply(new BigDecimal("-1"));
	    	return "-"+d1.format(c);
	    }else{
	    	return d1.format(b);
	    }
    }
}
